#include <easy3d/core/vec.h>
#include <easy3d/renderer/text_renderer.h>
#include <easy3d/renderer/texture.h>
#include <easy3d/renderer/texture_manager.h>
#include <memory>
#include <sstream> // __str__
#include <string>
#include <string_view>
#include <vector>

#include <functional>
#include <pybind11/pybind11.h>
#include <string>
#include <pybind11/stl.h>


#ifndef BINDER_PYBIND11_TYPE_CASTER
	#define BINDER_PYBIND11_TYPE_CASTER
	PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr<T>, false)
	PYBIND11_DECLARE_HOLDER_TYPE(T, T*, false)
	PYBIND11_MAKE_OPAQUE(std::shared_ptr<void>)
#endif

void bind_easy3d_renderer_text_renderer(pybind11::module_& m)
{
	{ // easy3d::TextRenderer file:easy3d/renderer/text_renderer.h line:53
		pybind11::class_<easy3d::TextRenderer, std::shared_ptr<easy3d::TextRenderer>> cl(m, "TextRenderer", "TextRenderer enables quick and easy string rendering in OpenGL applications.\n\n \n\n \n It supports truetype (TTF) fonts and unicode strings. All glyphs are cached in OpenGL textures and\n      font rasterization is done using 'stb_truetype.h.\"\n      TextRenderer allows you to:\n          - switch between fonts;\n          - change character spacing;\n          - enable/disable kerning;\n \n\n For a large number of strings/characters, it is necessary to separate buffer creation and rendering.\n \n\n Performance evaluation.");
		cl.def( pybind11::init( [](){ return new easy3d::TextRenderer(); } ), "doc" );
		cl.def( pybind11::init( [](float const & a0){ return new easy3d::TextRenderer(a0); } ), "doc" , pybind11::arg("dpi_scale"));
		cl.def( pybind11::init( [](float const & a0, int const & a1){ return new easy3d::TextRenderer(a0, a1); } ), "doc" , pybind11::arg("dpi_scale"), pybind11::arg("texture_size"));
		cl.def( pybind11::init<float, int, bool>(), pybind11::arg("dpi_scale"), pybind11::arg("texture_size"), pybind11::arg("mipmaps") );

		cl.def( pybind11::init( [](easy3d::TextRenderer const &o){ return new easy3d::TextRenderer(o); } ) );

		pybind11::enum_<easy3d::TextRenderer::Align>(cl, "Align", pybind11::arithmetic(), "Horizontal alignment. *")
			.value("ALIGN_LEFT", easy3d::TextRenderer::ALIGN_LEFT)
			.value("ALIGN_RIGHT", easy3d::TextRenderer::ALIGN_RIGHT)
			.value("ALIGN_CENTER", easy3d::TextRenderer::ALIGN_CENTER)
			.export_values();

		cl.def("add_font", (bool (easy3d::TextRenderer::*)(const std::string &)) &easy3d::TextRenderer::add_font, "Add a font from a file. This function must be called at least once to add a font.\n \n\n The font file (.ttf, etc).\n\nC++: easy3d::TextRenderer::add_font(const std::string &) --> bool", pybind11::arg("font_file"));
		cl.def("num_fonts", (std::size_t (easy3d::TextRenderer::*)() const) &easy3d::TextRenderer::num_fonts, "The number of available fonts.\n\nC++: easy3d::TextRenderer::num_fonts() const --> std::size_t");
		cl.def("font_names", (const class std::vector<std::string> & (easy3d::TextRenderer::*)() const) &easy3d::TextRenderer::font_names, "The names of available fonts.\n\nC++: easy3d::TextRenderer::font_names() const --> const class std::vector<std::string> &", pybind11::return_value_policy::automatic);
		cl.def("draw", [](easy3d::TextRenderer const &o, const std::string & a0, float const & a1, float const & a2, float const & a3) -> float { return o.draw(a0, a1, a2, a3); }, "", pybind11::arg("text"), pybind11::arg("x"), pybind11::arg("y"), pybind11::arg("font_size"));
		cl.def("draw", [](easy3d::TextRenderer const &o, const std::string & a0, float const & a1, float const & a2, float const & a3, int const & a4) -> float { return o.draw(a0, a1, a2, a3, a4); }, "", pybind11::arg("text"), pybind11::arg("x"), pybind11::arg("y"), pybind11::arg("font_size"), pybind11::arg("font_id"));
		cl.def("draw", [](easy3d::TextRenderer const &o, const std::string & a0, float const & a1, float const & a2, float const & a3, int const & a4, const class easy3d::Vec<3, float> & a5) -> float { return o.draw(a0, a1, a2, a3, a4, a5); }, "", pybind11::arg("text"), pybind11::arg("x"), pybind11::arg("y"), pybind11::arg("font_size"), pybind11::arg("font_id"), pybind11::arg("font_color"));
		cl.def("draw", (float (easy3d::TextRenderer::*)(const std::string &, float, float, float, int, const class easy3d::Vec<3, float> &, bool) const) &easy3d::TextRenderer::draw, "Draw the text.\n \n\n The string to be drawn.\n \n\n The x-coordinate of the starting position, relative to the left edge of the content area.\n \n\n The y-coordinate of the starting position. If upper_left is true, this position is relative to the\n        top edge of the content area. Otherwise, it is relative to the bottom edge of the content area.\n \n\n The font size.\n \n\n The id of the font used to draw the text, which is generated by calling to add_font(). 0 is\n        the first font, 1 is the second, etc.\n \n\n The font color.\n \n\n True to define the origin at the upper left corner of the content area. Otherwise it is\n        defined at the bottom left corner of the content area.\n \n\n The end position of the x-coordinate. This allows you to draw another string after the previous one.\n\n \n: This function will draw the text in one line and thus line breaks (i.e., \"\\n\") will be ignored.\n\nC++: easy3d::TextRenderer::draw(const std::string &, float, float, float, int, const class easy3d::Vec<3, float> &, bool) const --> float", pybind11::arg("text"), pybind11::arg("x"), pybind11::arg("y"), pybind11::arg("font_size"), pybind11::arg("font_id"), pybind11::arg("font_color"), pybind11::arg("upper_left"));
		cl.def("set_character_spacing", (void (easy3d::TextRenderer::*)(float)) &easy3d::TextRenderer::set_character_spacing, "Set the spacing between consecutive characters. The default character spacing is 0.\n \n\n The expected character spacing.\n\nC++: easy3d::TextRenderer::set_character_spacing(float) --> void", pybind11::arg("spacing"));
		cl.def("character_spacing", (float (easy3d::TextRenderer::*)() const) &easy3d::TextRenderer::character_spacing, "Query the spacing between consecutive characters.\n \n\n The spacing between consecutive characters.\n\nC++: easy3d::TextRenderer::character_spacing() const --> float");
		cl.def("set_kerning", (void (easy3d::TextRenderer::*)(bool)) &easy3d::TextRenderer::set_kerning, "Set kerning.\n \n\n The expected kerning behavior.\n\nC++: easy3d::TextRenderer::set_kerning(bool) --> void", pybind11::arg("kerning"));
		cl.def("kerning", (bool (easy3d::TextRenderer::*)() const) &easy3d::TextRenderer::kerning, "Query the kerning behavior. Kerning is disabled by default.\n \n\n The kerning behavior.\n\nC++: easy3d::TextRenderer::kerning() const --> bool");
		cl.def("font_height", (float (easy3d::TextRenderer::*)(float) const) &easy3d::TextRenderer::font_height, "Query the height of the font.\n \n\n The font size.\n \n\n The height of the font in pixels.\n\nC++: easy3d::TextRenderer::font_height(float) const --> float", pybind11::arg("font_size"));
		cl.def("string_width", (float (easy3d::TextRenderer::*)(const std::string &, float) const) &easy3d::TextRenderer::string_width, "Query the width of a string (treated as if with no space between characters). Useful to position a string.\n For example, with the string width, its X-center can be computed as: viewer_width * 0.5 - string_width * 0.5.\n \n\n The font size.\n \n\n The width of the string in pixels.\n\nC++: easy3d::TextRenderer::string_width(const std::string &, float) const --> float", pybind11::arg("str"), pybind11::arg("font_size"));
		cl.def("string_height", (float (easy3d::TextRenderer::*)(const std::string &, float) const) &easy3d::TextRenderer::string_height, "Query the height of a string.\n \n\n The font size.\n \n\n The height of the string in pixels.\n\nC++: easy3d::TextRenderer::string_height(const std::string &, float) const --> float", pybind11::arg("str"), pybind11::arg("font_size"));
		cl.def("assign", (class easy3d::TextRenderer & (easy3d::TextRenderer::*)(const class easy3d::TextRenderer &)) &easy3d::TextRenderer::operator=, "C++: easy3d::TextRenderer::operator=(const class easy3d::TextRenderer &) --> class easy3d::TextRenderer &", pybind11::return_value_policy::automatic, pybind11::arg(""));
	}
	{ // easy3d::Texture file:easy3d/renderer/texture.h line:44
		pybind11::class_<easy3d::Texture, std::shared_ptr<easy3d::Texture>> cl(m, "Texture", "OpenGL texture.\n\n \n\n \n currently only TEXTURE_2D is supported");

		pybind11::enum_<easy3d::Texture::WrapMode>(cl, "WrapMode", pybind11::arithmetic(), "")
			.value("CLAMP_TO_EDGE", easy3d::Texture::CLAMP_TO_EDGE)
			.value("REPEAT", easy3d::Texture::REPEAT)
			.export_values();


		pybind11::enum_<easy3d::Texture::FilterMode>(cl, "FilterMode", pybind11::arithmetic(), "")
			.value("NEAREST", easy3d::Texture::NEAREST)
			.value("LINEAR", easy3d::Texture::LINEAR)
			.export_values();

		cl.def_static("create", [](const std::string & a0) -> easy3d::Texture * { return easy3d::Texture::create(a0); }, "", pybind11::return_value_policy::automatic, pybind11::arg("image_file"));
		cl.def_static("create", [](const std::string & a0, enum easy3d::Texture::WrapMode const & a1) -> easy3d::Texture * { return easy3d::Texture::create(a0, a1); }, "", pybind11::return_value_policy::automatic, pybind11::arg("image_file"), pybind11::arg("wrap"));
		cl.def_static("create", (class easy3d::Texture * (*)(const std::string &, enum easy3d::Texture::WrapMode, enum easy3d::Texture::FilterMode)) &easy3d::Texture::create, "Creates a texture from an image file.\n \n\n\n \n The created texture.\n\nC++: easy3d::Texture::create(const std::string &, enum easy3d::Texture::WrapMode, enum easy3d::Texture::FilterMode) --> class easy3d::Texture *", pybind11::return_value_policy::automatic, pybind11::arg("image_file"), pybind11::arg("wrap"), pybind11::arg("filter"));
		cl.def_static("create", [](const class std::vector<unsigned char> & a0, int const & a1, int const & a2, int const & a3) -> easy3d::Texture * { return easy3d::Texture::create(a0, a1, a2, a3); }, "", pybind11::return_value_policy::automatic, pybind11::arg("rgb_data"), pybind11::arg("width"), pybind11::arg("height"), pybind11::arg("comp"));
		cl.def_static("create", [](const class std::vector<unsigned char> & a0, int const & a1, int const & a2, int const & a3, enum easy3d::Texture::WrapMode const & a4) -> easy3d::Texture * { return easy3d::Texture::create(a0, a1, a2, a3, a4); }, "", pybind11::return_value_policy::automatic, pybind11::arg("rgb_data"), pybind11::arg("width"), pybind11::arg("height"), pybind11::arg("comp"), pybind11::arg("wrap"));
		cl.def_static("create", (class easy3d::Texture * (*)(const class std::vector<unsigned char> &, int, int, int, enum easy3d::Texture::WrapMode, enum easy3d::Texture::FilterMode)) &easy3d::Texture::create, "Creates a texture from the given image data.\n \n\n The image data.\n \n\n The width (i.e., number of columns) of the image.\n \n\n The rows (i.e., number of rows) of the image.\n \n\n The number of components for each pixel (e.g., 3 for RGB)\n \n\n The created texture.\n\nC++: easy3d::Texture::create(const class std::vector<unsigned char> &, int, int, int, enum easy3d::Texture::WrapMode, enum easy3d::Texture::FilterMode) --> class easy3d::Texture *", pybind11::return_value_policy::automatic, pybind11::arg("rgb_data"), pybind11::arg("width"), pybind11::arg("height"), pybind11::arg("comp"), pybind11::arg("wrap"), pybind11::arg("filter"));
		cl.def("id", (unsigned int (easy3d::Texture::*)() const) &easy3d::Texture::id, "C++: easy3d::Texture::id() const --> unsigned int");
		cl.def("name", (const std::string & (easy3d::Texture::*)() const) &easy3d::Texture::name, "C++: easy3d::Texture::name() const --> const std::string &", pybind11::return_value_policy::automatic);
		cl.def("bind", [](easy3d::Texture const &o) -> void { return o.bind(); }, "");
		cl.def("bind", (void (easy3d::Texture::*)(int) const) &easy3d::Texture::bind, "C++: easy3d::Texture::bind(int) const --> void", pybind11::arg("unit"));
		cl.def("release", (void (easy3d::Texture::*)() const) &easy3d::Texture::release, "C++: easy3d::Texture::release() const --> void");
		cl.def("width", (int (easy3d::Texture::*)() const) &easy3d::Texture::width, "C++: easy3d::Texture::width() const --> int");
		cl.def("height", (int (easy3d::Texture::*)() const) &easy3d::Texture::height, "C++: easy3d::Texture::height() const --> int");
		cl.def("channels", (int (easy3d::Texture::*)() const) &easy3d::Texture::channels, "C++: easy3d::Texture::channels() const --> int");
		cl.def("wrap_mode", (enum easy3d::Texture::WrapMode (easy3d::Texture::*)() const) &easy3d::Texture::wrap_mode, "C++: easy3d::Texture::wrap_mode() const --> enum easy3d::Texture::WrapMode");
		cl.def("filter_mode", (enum easy3d::Texture::FilterMode (easy3d::Texture::*)() const) &easy3d::Texture::filter_mode, "C++: easy3d::Texture::filter_mode() const --> enum easy3d::Texture::FilterMode");
	}
	// easy3d::discretize_image(class std::vector<unsigned char> &, int, int, int, int) file:easy3d/renderer/texture.h line:122
	M("easy3d").def("discretize_image", (void (*)(class std::vector<unsigned char> &, int, int, int, int)) &easy3d::discretize_image, "Discretize a gradually varying-color (from left to right) image into a set of uniform colored vertical\n        stripes.\n \n\n The input data to be discretized.\n \n\n The width of the image (i.e., number of pixels in a row).\n \n\n The height of the image (i.e., number of pixels in a column).\n \n\n The number or color component per pixel.\n \n\n The number of stripes. The image will remain unmodified if num_stripes >= image width.\n\nC++: easy3d::discretize_image(class std::vector<unsigned char> &, int, int, int, int) --> void", pybind11::arg("data"), pybind11::arg("width"), pybind11::arg("height"), pybind11::arg("channels"), pybind11::arg("num_stripes"));

	{ // easy3d::TextureManager file:easy3d/renderer/texture_manager.h line:53
		pybind11::class_<easy3d::TextureManager, std::shared_ptr<easy3d::TextureManager>> cl(m, "TextureManager", "Management of OpenGL textures.\n\n \n\n \n A texture can be shared by multiple models, so it is wise to have a single instance of a texture.\n TextureManager manages the texture creation and memories. It ensures no duplication.\n\n \n Make sure to call terminate() to destroy existing textures before the OpenGL context is deleted.\n\n \n Allow to change the wrap/filter mode (i.e., multiple textures of different parameters from the same image).");
		cl.def( pybind11::init( [](){ return new easy3d::TextureManager(); } ) );
		cl.def_static("request", [](const std::string & a0) -> easy3d::Texture * { return easy3d::TextureManager::request(a0); }, "", pybind11::return_value_policy::automatic, pybind11::arg("image_file"));
		cl.def_static("request", [](const std::string & a0, enum easy3d::Texture::WrapMode const & a1) -> easy3d::Texture * { return easy3d::TextureManager::request(a0, a1); }, "", pybind11::return_value_policy::automatic, pybind11::arg("image_file"), pybind11::arg("wrap"));
		cl.def_static("request", (class easy3d::Texture * (*)(const std::string &, enum easy3d::Texture::WrapMode, enum easy3d::Texture::FilterMode)) &easy3d::TextureManager::request, "Request a texture from the image file.\n \n\n The generated texture has a unique identifier of its full-path file name. If a texture with the same\n          identifier is requested again, no new texture will be generated and the existing texture is returned.\n \n\n The full path to the image file.\n \n\n The wrap mode.\n \n\n The filter mode.\n \n\n The texture created from the image.\n\nC++: easy3d::TextureManager::request(const std::string &, enum easy3d::Texture::WrapMode, enum easy3d::Texture::FilterMode) --> class easy3d::Texture *", pybind11::return_value_policy::automatic, pybind11::arg("image_file"), pybind11::arg("wrap"), pybind11::arg("filter"));
		cl.def_static("request", [](const std::string & a0, int const & a1) -> easy3d::Texture * { return easy3d::TextureManager::request(a0, a1); }, "", pybind11::return_value_policy::automatic, pybind11::arg("image_file"), pybind11::arg("num_stripes"));
		cl.def_static("request", [](const std::string & a0, int const & a1, enum easy3d::Texture::WrapMode const & a2) -> easy3d::Texture * { return easy3d::TextureManager::request(a0, a1, a2); }, "", pybind11::return_value_policy::automatic, pybind11::arg("image_file"), pybind11::arg("num_stripes"), pybind11::arg("wrap"));
		cl.def_static("request", (class easy3d::Texture * (*)(const std::string &, int, enum easy3d::Texture::WrapMode, enum easy3d::Texture::FilterMode)) &easy3d::TextureManager::request, "Request a texture for rendering scalar fields from a gradually varying (from left to right) color\n        image given its file name.\n \n\n This method allows to sample the original image into a specified number of vertical stripes. The\n          generated texture has a unique identifier in the format: \"file_name|num_stripes\". If a texture with\n          the same identifier is requested again, no new texture will be generated and the existing one is\n          returned.\n \n\n The full path to the image file.\n \n\n The number of stripes. If num_stripes == image_width, no sampling will occur.\n \n\n The wrap mode.\n \n\n The filter mode.\n \n\n The texture created from the image.\n\nC++: easy3d::TextureManager::request(const std::string &, int, enum easy3d::Texture::WrapMode, enum easy3d::Texture::FilterMode) --> class easy3d::Texture *", pybind11::return_value_policy::automatic, pybind11::arg("image_file"), pybind11::arg("num_stripes"), pybind11::arg("wrap"), pybind11::arg("filter"));
		cl.def_static("request", [](int const & a0, int const & a1) -> easy3d::Texture * { return easy3d::TextureManager::request(a0, a1); }, "", pybind11::return_value_policy::automatic, pybind11::arg("num_stripes"), pybind11::arg("stride"));
		cl.def_static("request", [](int const & a0, int const & a1, enum easy3d::Texture::WrapMode const & a2) -> easy3d::Texture * { return easy3d::TextureManager::request(a0, a1, a2); }, "", pybind11::return_value_policy::automatic, pybind11::arg("num_stripes"), pybind11::arg("stride"), pybind11::arg("wrap"));
		cl.def_static("request", (class easy3d::Texture * (*)(int, int, enum easy3d::Texture::WrapMode, enum easy3d::Texture::FilterMode)) &easy3d::TextureManager::request, "Request a random color texture for rendering scalar fields. The texture will have a set of uniformly\n        colored vertical stripes.\n \n\n It first generates a random-colored image, where each row has \"num_colors\" color and each color\n          repeat \"stride\" times. Then, a texture is created from this image data. The generated texture has a\n          unique identifier in the format: \"random|num_stripes|stride\", where num_stripes and stride are\n          integer numbers. If the requested number of stripes and the stride match a previously generated\n          texture, no new texture will be generated and the existing texture is returned.\n \n\n The number of stripes in the texture.\n \n\n The width of each vertical strip. So the total width of the texture is: num_stripes * stride.\n \n\n The texture created.\n\nC++: easy3d::TextureManager::request(int, int, enum easy3d::Texture::WrapMode, enum easy3d::Texture::FilterMode) --> class easy3d::Texture *", pybind11::return_value_policy::automatic, pybind11::arg("num_stripes"), pybind11::arg("stride"), pybind11::arg("wrap"), pybind11::arg("filter"));
		cl.def_static("release", (void (*)(const class easy3d::Texture *)) &easy3d::TextureManager::release, "Release a texture (deallocate its memory).\n \n\n The texture to be released.\n\nC++: easy3d::TextureManager::release(const class easy3d::Texture *) --> void", pybind11::arg("texture"));
		cl.def_static("terminate", (void (*)()) &easy3d::TextureManager::terminate, "destroy all textures.\n\nC++: easy3d::TextureManager::terminate() --> void");
	}
}
